#include "ModBus.h"
#include <stdio.h>
#include "main.h"
#include "systemdata.h"
#include <stdlib.h>
#include "bat_afe.h"
#include "drv_rtc.h"
#include "drv_usart1.h"
#include "worktask.h"
#include "XgUpperMonitor.h"
#include "tsdb_save_data.h"
#include "drv_timer.h"
#include "delay.h"
#include "dvc.h"

static uint8_t SoftVersion[12];
static uint8_t Hard_ID[14];
static uint8_t sendBuf[256];

static void modbus_send_data(uint8_t *data,uint16_t len,uint8_t comNum){
	if(comNum == 1){
		usart1_send(data,len);
	}else if(comNum == 2){
		usart2_send(data,len);
	}else if(comNum == 4){
		usart4_send(data,len);
	}
}

static void readInputRegData(uint16_t regStartAddr,uint16_t regCount,uint8_t comNum){
	SysConfData_t *confInfo = getSysConfData();
	SysRunData_t  *runInfo = getSysRunData();
	uint16_t index = 0;
	
	memset(sendBuf,0,256);
	sendBuf[index++] = 0xab;
	sendBuf[index++] = 0x04;//读取多个输入寄存器
	sendBuf[index++] = (regCount * 2) & 0xff;
	uint16_t regAddr = regStartAddr;
	uint16_t i = 0;
	for (i = 0; i < regCount; i++,regAddr++) {
		switch(regAddr) {
			case 0: {//电池类型
				sendBuf[index++] = (confInfo->fctData.batType>>8)&0xff;
				sendBuf[index++] = confInfo->fctData.batType&0xff;
			}break;
			case 1: {//剩余容量
				uint16_t remCap = runInfo->rmCap_mAms/360000000;
				sendBuf[index++] = (remCap>>8)&0xff;
				sendBuf[index++] = remCap&0xff;
			}break;
			case 2: {//电芯串数
				sendBuf[index++] = (confInfo->fctData.batNum>>8)&0xff;
				sendBuf[index++] = confInfo->fctData.batNum&0xff;
			}break;
			case 3: {//电池状态
				sendBuf[index++] = (runInfo->batState>>8)&0xff;
				sendBuf[index++] = runInfo->batState&0xff;
			}break;
			case 4: {//电池总压
				sendBuf[index++] = ((runInfo->packVol * 10)>>8)&0xff;
				sendBuf[index++] = (runInfo->packVol * 10)&0xff;
			}break;
			case 5: {//充放电流H
				sendBuf[index++] = (runInfo->batCur>>24)&0xff;
				sendBuf[index++] = (runInfo->batCur>>16)&0xff;
			}break;
			case 6: {//充放电流L
				sendBuf[index++] = (runInfo->batCur>>8)&0xff;
				sendBuf[index++] = runInfo->batCur&0xff;
			}break;
			case 7: {//电池SOC
				uint16_t soc = ((uint16_t)runInfo->batSoc)*10;
				sendBuf[index++] = (soc>>8)&0xff;
				sendBuf[index++] = soc&0xff;
			}break;
			case 8: {//电池SOH
				uint16_t soh = runInfo->batSoh;
				soh *= 10;
				sendBuf[index++] = (soh>>8)&0xff;
				sendBuf[index++] = soh&0xff;
			}break;
			case 9: {//单体电压1
				sendBuf[index++] = (runInfo->batVol[0]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[0]&0xff;
			}break;
			case 10: {//单体电压2
				sendBuf[index++] = (runInfo->batVol[1]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[1]&0xff;
			}break;
			case 11: {//单体电压3
				sendBuf[index++] = (runInfo->batVol[2]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[2]&0xff;
			}break;
			case 12: {//单体电压4
				sendBuf[index++] = (runInfo->batVol[3]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[3]&0xff;
			}break;
			case 13: {//单体电压5
				sendBuf[index++] = (runInfo->batVol[4]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[4]&0xff;
			}break;
			case 14: {//单体电压6
				sendBuf[index++] = (runInfo->batVol[5]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[5]&0xff;
			}break;
			case 15: {//单体电压7
				sendBuf[index++] = (runInfo->batVol[6]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[6]&0xff;
			}break;
			case 16: {//单体电压8
				sendBuf[index++] = (runInfo->batVol[7]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[7]&0xff;
			}break;
			case 17: {//单体电压9
				sendBuf[index++] = (runInfo->batVol[8]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[8]&0xff;
			}break;
			case 18: {//单体电压10
				sendBuf[index++] = (runInfo->batVol[9]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[9]&0xff;
			}break;
			case 19: {//单体电压11
				sendBuf[index++] = (runInfo->batVol[10]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[10]&0xff;
			}break;
			case 20: {//单体电压12
				sendBuf[index++] = (runInfo->batVol[11]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[11]&0xff;
			}break;
			case 21: {//单体电压13
				sendBuf[index++] = (runInfo->batVol[12]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[12]&0xff;
			}break;
			case 22: {//单体电压14
				sendBuf[index++] = (runInfo->batVol[13]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[13]&0xff;
			}break;
			case 23: {//单体电压15
				sendBuf[index++] = (runInfo->batVol[14]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[14]&0xff;
			}break;
			case 24: {//单体电压16
				sendBuf[index++] = (runInfo->batVol[15]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[15]&0xff;
			}break;
			case 25: {//单体电压17
				sendBuf[index++] = (runInfo->batVol[16]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[16]&0xff;
			}break;
			case 26: {//单体电压18
				sendBuf[index++] = (runInfo->batVol[17]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[17]&0xff;
			}break;
			case 27: {//单体电压19
				sendBuf[index++] = (runInfo->batVol[18]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[18]&0xff;
			}break;
			case 28: {//单体电压20
				sendBuf[index++] = (runInfo->batVol[19]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[19]&0xff;
			}break;
			case 29: {//单体电压21
				sendBuf[index++] = (runInfo->batVol[20]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[20]&0xff;
			}break;
			case 30: {//单体电压22
				sendBuf[index++] = (runInfo->batVol[21]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[21]&0xff;
			}break;
			case 31: {//单体电压23
				sendBuf[index++] = (runInfo->batVol[22]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[22]&0xff;
			}break;
			case 32: {//单体电压24
				sendBuf[index++] = (runInfo->batVol[23]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[23]&0xff;
			}break;
			case 33: {//单体电压25
				sendBuf[index++] = (runInfo->batVol[24]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[24]&0xff;
			}break;
			case 34: {//单体电压26
				sendBuf[index++] = (runInfo->batVol[25]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[25]&0xff;
			}break;
			case 35: {//单体电压27
				sendBuf[index++] = (runInfo->batVol[26]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[26]&0xff;
			}break;
			case 36: {//单体电压28
				sendBuf[index++] = (runInfo->batVol[27]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[27]&0xff;
			}break;
			case 37: {//单体电压29
				sendBuf[index++] = (runInfo->batVol[28]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[28]&0xff;
			}break;
			case 38: {//单体电压30
				sendBuf[index++] = (runInfo->batVol[29]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[29]&0xff;
			}break;
			case 39: {//单体电压31
				sendBuf[index++] = (runInfo->batVol[30]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[30]&0xff;
			}break;
			case 40: {//单体电压32
				sendBuf[index++] = (runInfo->batVol[31]>>8)&0xff;
				sendBuf[index++] = runInfo->batVol[31]&0xff;
			}break;
			case 41: {//功率管温度
				int16_t temp = runInfo->mosTemp;
				sendBuf[index++] = (temp>>8)&0xff;
				sendBuf[index++] = temp&0xff;
			}break;
			case 42: {//环境温度
				int16_t temp = runInfo->envTemp;
				sendBuf[index++] = (temp>>8)&0xff;
				sendBuf[index++] = temp&0xff;
			}break;
			case 43: {//电池温度传感器数量2个
				sendBuf[index++] = (2>>8)&0xff;
				sendBuf[index++] = 2&0xff;
			}break;
			case 44: {//电池温度1
				int16_t temp = runInfo->tempOne;
				sendBuf[index++] = (temp>>8)&0xff;
				sendBuf[index++] = temp&0xff;
			}break;
			case 45: {//电池温度2
				int16_t temp = runInfo->tempTwo;
				sendBuf[index++] = (temp>>8)&0xff;
				sendBuf[index++] = temp&0xff;
			}break;
			case 46: {//电池温度3
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 47: {//电池温度4
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 48: {//电池温度5
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 49: {//电池温度6
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 50: {//电池温度7
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 51: {//电池温度8
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 52: {//电池温度9
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 53: {//电池温度10
				sendBuf[index++] = (0>>8)&0xff;
				sendBuf[index++] = 0&0xff;
			}break;
			case 54: {//单体最高电压
				sendBuf[index++] = (runInfo->batMaxVol>>8)&0xff;
				sendBuf[index++] = runInfo->batMaxVol&0xff;
			}break;
			case 55: {//单体最低电压
				sendBuf[index++] = (runInfo->batMinVol>>8)&0xff;
				sendBuf[index++] = runInfo->batMinVol&0xff;
			}break;
			case 56: {//单体最大压差
				sendBuf[index++] = (runInfo->maxDiffVol>>8)&0xff;
				sendBuf[index++] = runInfo->maxDiffVol&0xff;
			}break;
			case 57: {//电压最高单体编号
				sendBuf[index++] = (runInfo->batMaxNum>>8)&0xff;
				sendBuf[index++] = runInfo->batMaxNum&0xff;
			}break;
			case 58: {//电压最低单体编号
				sendBuf[index++] = (runInfo->batMinNum>>8)&0xff;
				sendBuf[index++] = runInfo->batMinNum&0xff;
			}break;
			case 59: {//循环次数
				sendBuf[index++] = (confInfo->fctData.cycleTimes.value>>8)&0xff;
				sendBuf[index++] = confInfo->fctData.cycleTimes.value&0xff;
			}break;
			case 60: {//充电需求电压
				sendBuf[index++] = ((runInfo->chgReqVol*10)>>8)&0xff;
				sendBuf[index++] = (runInfo->chgReqVol*10)&0xff;
			}break;
			case 61: {//充电需求电流
				sendBuf[index++] = (runInfo->chgReqCur>>8)&0xff;
				sendBuf[index++] = runInfo->chgReqCur&0xff;
			}break;
			case 62: {//均衡状态bit16~bit31
				sendBuf[index++] = (runInfo->balState>>24)&0xff;
				sendBuf[index++] = (runInfo->balState>>16)&0xff;
			}break;
			case 63: {//均衡状态bit0~bit15
				sendBuf[index++] = (runInfo->balState>>8)&0xff;
				sendBuf[index++] = runInfo->balState&0xff;
			}break;
			case 64: {//开关状态
				sendBuf[index++] = (runInfo->sysSwState.stateByte>>8)&0xff;
				sendBuf[index++] = runInfo->sysSwState.stateByte&0xff;
			}break;
			case 65: {//功能状态
				sendBuf[index++] = (runInfo->funcSwState.stateByte>>8)&0xff;
				sendBuf[index++] = runInfo->funcSwState.stateByte&0xff;
			}break;
			case 66: {//单体高压告警状态H
				sendBuf[index++] = (runInfo->volWarnByte.cellHgVolWarn>>24)&0xff;
				sendBuf[index++] = (runInfo->volWarnByte.cellHgVolWarn>>16)&0xff;
			}break;
			case 67: {//单体高压告警状态L
				sendBuf[index++] = (runInfo->volWarnByte.cellHgVolWarn>>8)&0xff;
				sendBuf[index++] = runInfo->volWarnByte.cellHgVolWarn&0xff;
			}break;
			case 68: {//单体低压告警状态H
				sendBuf[index++] = (runInfo->volWarnByte.cellLowVolWarn>>24)&0xff;
				sendBuf[index++] = (runInfo->volWarnByte.cellLowVolWarn>>16)&0xff;
			}break;
			case 69: {//单体低压告警状态L
				sendBuf[index++] = (runInfo->volWarnByte.cellLowVolWarn>>8)&0xff;
				sendBuf[index++] = runInfo->volWarnByte.cellLowVolWarn&0xff;
			}break;
			case 70: {//单体过压故障状态H
				sendBuf[index++] = (runInfo->volProtByte.cellHgVolProt>>24)&0xff;
				sendBuf[index++] = (runInfo->volProtByte.cellHgVolProt>>16)&0xff;
			}break;
			case 71: {//单体过压故障状态L
				sendBuf[index++] = (runInfo->volProtByte.cellHgVolProt>>8)&0xff;
				sendBuf[index++] = runInfo->volProtByte.cellHgVolProt&0xff;
			}break;
			case 72: {//单体欠压故障状态H
				sendBuf[index++] = (runInfo->volProtByte.cellLowVolProt>>24)&0xff;
				sendBuf[index++] = (runInfo->volProtByte.cellLowVolProt>>16)&0xff;
			}break;
			case 73: {//单体欠压故障状态L
				sendBuf[index++] = (runInfo->volProtByte.cellLowVolProt>>8)&0xff;
				sendBuf[index++] = runInfo->volProtByte.cellLowVolProt&0xff;
			}break;
			case 74: {//电池电压状态
				sendBuf[index++] = runInfo->volProtByte.volProt.byte&0xff;
				sendBuf[index++] = runInfo->volWarnByte.volWarn.byte&0xff;
			}break;
			case 75: {//温度告警状态
				sendBuf[index++] = (runInfo->tempWarnByte.byte>>8)&0xff;
				sendBuf[index++] = runInfo->tempWarnByte.byte&0xff;
			}break;
			case 76: {//温度故障状态
				sendBuf[index++] = (runInfo->tempProtByte.byte>>8)&0xff;
				sendBuf[index++] = runInfo->tempProtByte.byte&0xff;
			}break;
			case 77: {//电流故障状态
				sendBuf[index++] = (runInfo->curProtByte.byte>>8)&0xff;
				sendBuf[index++] = runInfo->curProtByte.byte&0xff;
			}break;
			case 78: {//模拟前端故障状态
				sendBuf[index++] = (runInfo->afeProtByte.byte>>8)&0xff;
				sendBuf[index++] = runInfo->afeProtByte.byte&0xff;
			}break;
			case 79: {//BMS时钟-年月
				getRtcTimeHex((char *)runInfo->rtcTime);
				sendBuf[index++] = runInfo->rtcTime[0]&0xff;
				sendBuf[index++] = runInfo->rtcTime[1]&0xff;
			}break;
			case 80: {//BMS时钟-日时
				sendBuf[index++] = runInfo->rtcTime[2]&0xff;
				sendBuf[index++] = runInfo->rtcTime[3]&0xff;
			}break;
			case 81: {//BMS时钟-分秒
				sendBuf[index++] = runInfo->rtcTime[4]&0xff;
				sendBuf[index++] = runInfo->rtcTime[5]&0xff;
			}break;
			case 82: {//bms软件版本号
				uint8_t *pSoftVer = (uint8_t *)SOFT_VERSION;
				sendBuf[index++] = pSoftVer[0]&0xff;
				sendBuf[index++] = pSoftVer[1]&0xff;
			}break;
			case 83: {//bms软件版本号
				uint8_t *pSoftVer = (uint8_t *)SOFT_VERSION;
				sendBuf[index++] = pSoftVer[2]&0xff;
				sendBuf[index++] = pSoftVer[3]&0xff;
			}break;
			case 84: {//bms软件版本号
				uint8_t *pSoftVer = (uint8_t *)SOFT_VERSION;
				sendBuf[index++] = pSoftVer[4]&0xff;
				sendBuf[index++] = pSoftVer[5]&0xff;
			}break;
			case 85: {//bms软件版本号
				uint8_t *pSoftVer = (uint8_t *)SOFT_VERSION;
				sendBuf[index++] = pSoftVer[6]&0xff;
				sendBuf[index++] = pSoftVer[7]&0xff;
			}break;
			case 86: {//bms软件版本号
				uint8_t *pSoftVer = (uint8_t *)SOFT_VERSION;
				sendBuf[index++] = pSoftVer[8]&0xff;
				sendBuf[index++] = pSoftVer[9]&0xff;
			}break;
			case 87: {//bms软件版本号
				uint8_t *pSoftVer = (uint8_t *)SOFT_VERSION;
				sendBuf[index++] = pSoftVer[10]&0xff;
				sendBuf[index++] = pSoftVer[11]&0xff;
			}break;
		}
	}
	uint16_t crc = XgBmsProtocolCrc(sendBuf, index);
	sendBuf[index++] = (crc>>8) & 0xff;
	sendBuf[index++] = crc & 0xff;
	modbus_send_data(sendBuf,index,comNum);
}

static void readMultiHoldRegData(uint16_t regStartAddr,uint16_t regCount,uint8_t comNum){
	SysConfData_t *confInfo = getSysConfData();
	SysRunData_t  *runInfo = getSysRunData();
	uint8_t index = 0;
	memset(sendBuf,0,256);
	sendBuf[index++] = 0xab;
	sendBuf[index++] = 0x03;//写多个寄存器
	sendBuf[index++] = (regCount*2) & 0xff;
	uint16_t i = 0;
	for (i = 0; i < regCount; i++, regStartAddr ++) {
		switch (regStartAddr) {
			case 0: {//预留
				sendBuf[index++] = (0 >> 8) & 0xff;
				sendBuf[index++] = 0 & 0xff;
			}break;
			case 1: { // 电池类型
				sendBuf[index++] = (confInfo->fctData.batType >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.batType  & 0xff;
			}break;
			case 2: { // 电池串数
				sendBuf[index++] = (confInfo->fctData.batNum >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.batNum  & 0xff;
			}break;
			case 3: {// 硬件ID
				sendBuf[index++] = confInfo->fctData.hdSerial[0] & 0xff;
				sendBuf[index++] = confInfo->fctData.hdSerial[1]  & 0xff;
			}break;
			case 4: {// 硬件ID
				sendBuf[index++] = confInfo->fctData.hdSerial[2] & 0xff;
				sendBuf[index++] = confInfo->fctData.hdSerial[3]  & 0xff;
			}break;
			case 5: {// 硬件ID
				sendBuf[index++] = confInfo->fctData.hdSerial[4] & 0xff;
				sendBuf[index++] = confInfo->fctData.hdSerial[5]  & 0xff;
			}break;
			case 6: {// 硬件ID
				sendBuf[index++] = confInfo->fctData.hdSerial[6] & 0xff;
				sendBuf[index++] = confInfo->fctData.hdSerial[7]  & 0xff;
			}break;
			case 7: {// 硬件ID
				sendBuf[index++] = confInfo->fctData.hdSerial[8] & 0xff;
				sendBuf[index++] = confInfo->fctData.hdSerial[9]  & 0xff;
			}break;
			case 8: {// 硬件ID
				sendBuf[index++] = confInfo->fctData.hdSerial[10] & 0xff;
				sendBuf[index++] = confInfo->fctData.hdSerial[11]  & 0xff;
			}break;
			case 9: {// 硬件ID
				sendBuf[index++] = confInfo->fctData.BtNum[0] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[1] & 0xff;
			}break;
			case 10: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[2] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[3] & 0xff;
			}break;
			case 11: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[4] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[5] & 0xff;
			}break;
			case 12: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[6] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[7] & 0xff;
			}break;
			case 13: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[8] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[9] & 0xff;
			}break;
			case 14: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[10] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[11] & 0xff;
			}break;
			case 15: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[12] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[13] & 0xff;
			}break;
			case 16: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[14] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[15] & 0xff;
			}break;
			case 17: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[16] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[17] & 0xff;
			}break;
			case 18: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[18] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[19] & 0xff;
			}break;
			case 19: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[20] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[21] & 0xff;
			}break;
			case 20: {// 电池BT码
				sendBuf[index++] = confInfo->fctData.BtNum[22] & 0xff;
				sendBuf[index++] = confInfo->fctData.BtNum[23] & 0xff;
			}break;
			case 21: {// 标称容量
				sendBuf[index++] = (confInfo->fctData.normalCap.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.normalCap.value  & 0xff;
			}break;
			case 22: {// 实际容量
				sendBuf[index++] = (confInfo->fctData.realCap.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.realCap.value  & 0xff;
			}break;
			case 23: {// 循环次数
				sendBuf[index++] = (confInfo->fctData.cycleTimes.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.cycleTimes.value  & 0xff;
			}break;
			case 24: {// 预充时间
				sendBuf[index++] = (confInfo->fctData.preChargeTime.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.preChargeTime.value  & 0xff;
			}break;
			case 25: {// 单体关机电压
				sendBuf[index++] = (confInfo->fctData.poweroff_vol.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.poweroff_vol.value  & 0xff;
			}break;
			case 26: {// 唤醒电流
				sendBuf[index++] = (confInfo->fctData.wakeupCurrent.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.wakeupCurrent.value  & 0xff;
			}break;
			case 27: {// 钥匙检测使能
				sendBuf[index++] = (confInfo->fctData.otherParmByte.byte  >> 8) & 0xff;
				sendBuf[index++] = confInfo->fctData.otherParmByte.byte  & 0xff;
			}break;
			case 28: {//单体高压告警
				sendBuf[index++] = (confInfo->warnData.batVolHigh.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->warnData.batVolHigh.value  & 0xff;
			}break;
			case 29: {// 单体低压告警
				sendBuf[index++] = (confInfo->warnData.batVolLow.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->warnData.batVolLow.value  & 0xff;
			}break;
			case 30: {// 单体压差告警
				sendBuf[index++] = (confInfo->warnData.batVolDiff.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->warnData.batVolDiff.value  & 0xff;
			}break;
			case 31: {// 总压高压告警
				sendBuf[index++] = (confInfo->warnData.packVolHigh.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->warnData.packVolHigh.value  & 0xff;
			}break;
			case 32: {// 总压低压告警
				sendBuf[index++] = (confInfo->warnData.packVolLow.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->warnData.packVolLow.value  & 0xff;
			}break;
			case 33: {// 功率高温告警
				int16_t temp = confInfo->warnData.mosTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 34: {// 环境高温告警
				int16_t temp = confInfo->warnData.envTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 35: {//环境低温告警
				int16_t temp = confInfo->warnData.envTemplow;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 36: {// 充电高温告警
				int16_t temp = confInfo->warnData.chgTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 37: {// 充电低温告警
				int16_t temp = confInfo->warnData.chgTempLow;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 38: {// 放电高温告警
				int16_t temp = confInfo->warnData.dsgTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 39: {// 放电低温告警
				int16_t temp = confInfo->warnData.chgTempLow;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 40: {// 容量低告警
				sendBuf[index++] = (confInfo->warnData.socLow  >> 8) & 0xff;
				sendBuf[index++] = confInfo->warnData.socLow  & 0xff;
			}break;
			case 41: {// 单体一级过压故障
				sendBuf[index++] = (confInfo->errorData.batVolHigh.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolHigh.value  & 0xff;
			}break;
			case 42: {// 单体一级过压恢复
				sendBuf[index++] = (confInfo->errorData.batVolHighRecover.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolHighRecover.value  & 0xff;
			}break;
			case 43: {// 单体一级过压判定时间
				sendBuf[index++] = (confInfo->errorData.batVolHighTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolHighTime  & 0xff;
			}break;
			case 44: {// 单体一级欠压故障
				sendBuf[index++] = (confInfo->errorData.batVolLow.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolLow.value  & 0xff;
			}break;
			case 45: {// 单体一级欠压恢复
				sendBuf[index++] = (confInfo->errorData.batVolLowRecover.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolLowRecover.value  & 0xff;
			}break;
			case 46: {//单体一级欠压判定时间
				sendBuf[index++] = (confInfo->errorData.batVolLowTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolLowTime  & 0xff;
			}break;
			case 47: {// 单体二级过压故障
				sendBuf[index++] = (confInfo->errorData.sov_vol.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.sov_vol.value  & 0xff;
			}break;
			case 48: {// 单体二级欠压故障
				sendBuf[index++] = (confInfo->errorData.suv_vol.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.suv_vol.value  & 0xff;
			}break;
			case 49: {// 单体二级过压、欠压判定时间
				uint16_t sov_suv_dly= (g_AfeRegs.R115.CUVD & 0xff)-7;
				sendBuf[index++] = (sov_suv_dly  >> 8) & 0xff;
				sendBuf[index++] = sov_suv_dly  & 0xff;
			}break;
			case 50: {// 单体压差故障
				sendBuf[index++] = (confInfo->errorData.batVolDiff.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolDiff.value  & 0xff;
			}break;
			case 51: {// 单体压差恢复
				sendBuf[index++] = (confInfo->errorData.batVolDiffRecover.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolDiffRecover.value  & 0xff;
			}break;
			case 52: {// 单体压差故障判定时间
				sendBuf[index++] = (confInfo->errorData.batVolDiffTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batVolDiffTime  & 0xff;
			}break;
			case 53: {// 总压过压故障
				sendBuf[index++] = (confInfo->errorData.packVolHigh.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.packVolHigh.value  & 0xff;
			}break;
			case 54: {// 总压过压恢复
				sendBuf[index++] = (confInfo->errorData.packVolHighRecover.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.packVolHighRecover.value  & 0xff;
			}break;
			case 55: {// 总压过压故障判定时间
				sendBuf[index++] = (confInfo->errorData.packVolHighTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.packVolHighTime  & 0xff;
			}break;
			case 56: {// 总压欠压故障
				sendBuf[index++] = (confInfo->errorData.packVolLow.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.packVolLow.value  & 0xff;
			}break;
			case 57: {// 总压欠压恢复
				sendBuf[index++] = (confInfo->errorData.packVolLowRecover.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.packVolLowRecover.value  & 0xff;
			}break;
			case 58: {// 总压欠压故障判定时间
				sendBuf[index++] = (confInfo->errorData.packVolLowTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.packVolLowTime  & 0xff;
			}break;
			case 59: {// 功率过温故障
				int16_t temp = confInfo->errorData.mosTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 60: {// 功率过温恢复
				int16_t temp = confInfo->errorData.mosTempHighRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 61: {// 功率过温故障判定时间
				sendBuf[index++] = (confInfo->errorData.mosTempHighTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.mosTempHighTime  & 0xff;
			}break;
			case 62: {// 环境过温故障
				int16_t temp = confInfo->errorData.envTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 63: {// 环境过温恢复
				int16_t temp = confInfo->errorData.envTempHighRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 64: {// 环境过温故障判定时间
				sendBuf[index++] = (confInfo->errorData.envTempHighTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.envTempHighTime  & 0xff;
			}break;
			case 65: {// 环境欠温故障
				int16_t temp = confInfo->errorData.envTempLow;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 66: {// 环境欠温恢复
				int16_t temp = confInfo->errorData.envTempLowRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 67: {// 环境欠温故障判定时间
				sendBuf[index++] = (confInfo->errorData.envTempLowTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.envTempLowTime  & 0xff;
			}break;
			case 68: {// 充电过温保护
				int16_t temp = confInfo->errorData.chgTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 69: {// 充电过温恢复
				int16_t temp = confInfo->errorData.chgTempHighRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 70: {// 充电过温判定时间
				sendBuf[index++] = (confInfo->errorData.chgTempHighTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgTempHighTime  & 0xff;
			}break;
			case 71: {// 充电欠温保护
				int16_t temp = confInfo->errorData.chgTempLow;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 72: {// 充电欠温恢复
				int16_t temp = confInfo->errorData.chgTempLowRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 73: {// 充电欠温判定时间
				sendBuf[index++] = (confInfo->errorData.chgTempLowTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgTempLowTime  & 0xff;
			}break;
			case 74: {// 放电过温保护
				int16_t temp = confInfo->errorData.dsgTempHigh;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 75: {// 放电过温恢复
				int16_t temp = confInfo->errorData.dsgTempHighRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 76: {// 放电过温判定时间
				sendBuf[index++] = (confInfo->errorData.dsgTempHighTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgTempHighTime  & 0xff;
			}break;
			case 77: {// 放电欠温保护
				int16_t temp = confInfo->errorData.dsgTempLow;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 78: {// 放电欠温恢复
				int16_t temp = confInfo->errorData.dsgTempLowRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 79: {// 放电欠温判定时间
				sendBuf[index++] = (confInfo->errorData.dsgTempLowTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgTempLowTime  & 0xff;
			}break;
			case 80: {// 电池温差保护
				int16_t temp = confInfo->errorData.batTempDiff;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 81: {// 电池温差恢复
				int16_t temp = confInfo->errorData.batTempDiffRecover;
				sendBuf[index++] = (temp  >> 8) & 0xff;
				sendBuf[index++] = temp  & 0xff;
			}break;
			case 82: {// 电池温差保护判定时间
				sendBuf[index++] = (confInfo->errorData.batTempDiffTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.batTempDiffTime  & 0xff;
			}break;
			case 83: {// 一级充电过流保护
				sendBuf[index++] = (confInfo->errorData.chgOverCurrent.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurrent.value & 0xff;
			}break;
			case 84: {// 一级充电过流恢复时间
				sendBuf[index++] = (confInfo->errorData.chgOverCurRecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurRecoverTime.value & 0xff;
			}break;
			case 85: {// 一级充电过流判定时间
				sendBuf[index++] = (confInfo->errorData.chgOverCurrentTime  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurrentTime & 0xff;
			}break;
			case 86: {// 二级充电过流保护
				//uint16_t chgOverCurrent2 =g_AfeRegs.R90.OCC1T/CurrentSenseResistance_mR*0.25;
				sendBuf[index++] = (confInfo->errorData.chgOverCurrent2.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurrent2.value & 0xff;
			}break;
			case 87: {// 二级充电过流恢复时间
				sendBuf[index++] = (confInfo->errorData.chgOverCur2RecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCur2RecoverTime.value & 0xff;
			}break;
			case 88: {// 二级充电过流判定时间
				//uint16_t chgOverCur2Time=(g_AfeRegs.R92.OCC1D+1)*8/1000;
				sendBuf[index++] = (confInfo->errorData.chgOverCurrent2Time >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurrent2Time & 0xff;
			}break;
			case 89: {// 三级充电过流保护
				sendBuf[index++] = (confInfo->errorData.chgOverCurrent3.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurrent3.value & 0xff;
			}break;
			case 90: {// 三级充电过流恢复时间
				sendBuf[index++] = (confInfo->errorData.chgOverCur3RecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCur3RecoverTime.value & 0xff;
			}break;
			case 91: {// 三级充电过流判定时间
				sendBuf[index++] = (confInfo->errorData.chgOverCurrent3Time >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurrent3Time & 0xff;
			}break;
			case 92: {// 一级放电过流保护
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrent.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrent.value & 0xff;
			}break;
			case 93: {// 一级放电过流恢复时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCurRecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurRecoverTime.value & 0xff;
			}break;
			case 94: {// 一级放电过流判定时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrentTime >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrentTime & 0xff;
			}break;
			case 95: {// 二级放电过流保护
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrent2.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrent2.value & 0xff;
			}break;
			case 96: {// 二级放电过流恢复时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCur2RecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCur2RecoverTime.value & 0xff;
			}break;
			case 97: {// 二级放电过流判定时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrent2Time >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrent2Time & 0xff;
			}break;
			case 98: {// 三级放电过流保护
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrent3.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrent3.value & 0xff;
			}break;
			case 99: {// 三级放电过流恢复时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCur3RecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCur3RecoverTime.value & 0xff;
			}break;
			case 100: {// 三级放电过流判定时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrent3Time >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrent3Time & 0xff;
			}break;
			case 101: {// 四级放电过流保护
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrent4.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrent4.value & 0xff;
			}break;
			case 102: {// 四级放电过流恢复时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCur4RecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCur4RecoverTime.value & 0xff;
			}break;
			case 103: {// 四级放电过流判定时间
				sendBuf[index++] = (confInfo->errorData.dsgOverCurrent4Time.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.dsgOverCurrent4Time.value & 0xff;
			}break;
			case 104: {// 短路保护
				sendBuf[index++] = (confInfo->errorData.scdVol.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.scdVol.value & 0xff;
			}break;
			case 105: {// 短路判定时间
				sendBuf[index++] = (confInfo->errorData.scdVolTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.scdVolTime.value & 0xff;
			}break;
			case 106: {// 短路恢复时间
				sendBuf[index++] = (confInfo->errorData.scdRecoverTime.value >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.scdRecoverTime.value & 0xff;
			}break;
			case 107: {// 充电过流保护锁定次数
				sendBuf[index++] = (confInfo->errorData.chgOverCurLockTimes.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.chgOverCurLockTimes.value & 0xff;
			}break;
			case 108: {// 放电过流保护锁定次数
				sendBuf[index++] = (confInfo->errorData.disOverCurLockTimes.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.disOverCurLockTimes.value & 0xff;
			}break;
			case 109: {// 短路保护锁定次数
				sendBuf[index++] = (confInfo->errorData.scdLockTimes.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->errorData.scdLockTimes.value & 0xff;
			}break;
			case 110: {// 均衡开启电压
				sendBuf[index++] = (confInfo->balData.openVol.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->balData.openVol.value & 0xff;
			}break;
			case 111: {// 均衡开启压差
				sendBuf[index++] = (confInfo->balData.openDiffVol.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->balData.openDiffVol.value & 0xff;
			}break;
			case 112: {// 均衡关闭压差
				sendBuf[index++] = (confInfo->balData.endDiffVol.value  >> 8) & 0xff;
				sendBuf[index++] = confInfo->balData.endDiffVol.value & 0xff;
			}break;
		}
	}
	uint16_t crc = XgBmsProtocolCrc(sendBuf, index);
	sendBuf[index++] = (crc>>8) & 0xff;
	sendBuf[index++] = crc & 0xff;
	modbus_send_data(sendBuf,index,comNum);
}


//写单个保持寄存器数据
static void preSetSinHoldRegData(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	
	uint8_t index = 0;
	uint16_t RegData = 0;
	SysConfData_t *confInfo = getSysConfData();
	SysRunData_t *runinfo = getSysRunData();
	uint8_t send_data[255];
	
	uint8_t regAdressH = data[2];
	uint8_t regAdressL = data[3];
	uint16_t startHoldRegAdress = (regAdressH<<8)|regAdressL;
	
	uint8_t RegDataH = data[4];
	uint8_t RegDataL = data[5];
	RegData =(RegDataH<<8)|RegDataL;

	switch(startHoldRegAdress){
		case 1:{//电池类型
			confInfo->fctData.batType = RegData;
		}break;
		case 2:{//电池串数
			confInfo->fctData.batNum = RegData;
			Judge_BatNum();
		}break;
		case 3:{//硬件ID
			confInfo->fctData.hdSerial[0] = (RegData>>8)&0xff;
			confInfo->fctData.hdSerial[1] = RegData&0xff;
		}break;
		case 4:{//硬件ID
			confInfo->fctData.hdSerial[2] = (RegData>>8)&0xff;
			confInfo->fctData.hdSerial[3] = RegData&0xff;
		}break;
		case 5:{//硬件ID
			confInfo->fctData.hdSerial[4] = (RegData>>8)&0xff;
			confInfo->fctData.hdSerial[5] = RegData&0xff;
		}break;
		case 6:{//硬件ID
			confInfo->fctData.hdSerial[6] = (RegData>>8)&0xff;
			confInfo->fctData.hdSerial[7] = RegData&0xff;
		}break;
		case 7:{//硬件ID
			confInfo->fctData.hdSerial[8] = (RegData>>8)&0xff;
			confInfo->fctData.hdSerial[9] = RegData&0xff;
		}break;
		case 8:{//硬件ID
			confInfo->fctData.hdSerial[10] = (RegData>>8)&0xff;
			confInfo->fctData.hdSerial[11] = RegData&0xff;
		}break;
		case 9:{//电池BT码
			confInfo->fctData.BtNum[0] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[1] = RegData&0xff;
		}break;
		case 10:{//电池BT码
			confInfo->fctData.BtNum[2] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[3] = RegData&0xff;
		}break;
		case 11:{//电池BT码
			confInfo->fctData.BtNum[4] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[5] = RegData&0xff;
		}break;
		case 12:{//电池BT码
			confInfo->fctData.BtNum[6] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[7] = RegData&0xff;
		}break;
		case 13:{//电池BT码
			confInfo->fctData.BtNum[8] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[9] = RegData&0xff;
		}break;
		case 14:{//电池BT码
			confInfo->fctData.BtNum[10] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[11] = RegData&0xff;
		}break;
		case 15:{//电池BT码
			confInfo->fctData.BtNum[12] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[13] = RegData&0xff;
		}break;
		case 16:{//电池BT码
			confInfo->fctData.BtNum[14] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[15] = RegData&0xff;
		}break;
		case 17:{//电池BT码
			confInfo->fctData.BtNum[16] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[17] = RegData&0xff;
		}break;
		case 18:{//电池BT码
			confInfo->fctData.BtNum[18] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[19] = RegData&0xff;
		}break;
		case 19:{//电池BT码
			confInfo->fctData.BtNum[20] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[21] = RegData&0xff;
		}break;
		case 20:{//电池BT码
			confInfo->fctData.BtNum[22] = (RegData>>8)&0xff;
			confInfo->fctData.BtNum[23] = RegData&0xff;
		}break;
		case 21:{//标称容量
			confInfo->fctData.normalCap.value = RegData;
			runinfo->norCap_mAmS = ((uint64_t)confInfo->fctData.normalCap.value) * 360 * 1000 * 1000; // 实际容量初始化
		}break;
		case 22:{//实际容量
			confInfo->fctData.realCap.value = RegData;
			runinfo->realCap_mAms = ((uint64_t)confInfo->fctData.realCap.value) * 360 * 1000 * 1000;  // 实际容量初始化
		}break;
		case 23:{//循环次数
			confInfo->fctData.cycleTimes.value = RegData;
		}break;
		case 24:{//预充时间
			confInfo->fctData.preChargeTime.value = RegData;
		}break;
		case 25:{//单体关机电压
			confInfo->fctData.poweroff_vol.value = RegData;
		}break;
		case 26:{//唤醒电流
			confInfo->fctData.wakeupCurrent.value = RegData;
		}break;
		case 27:{//钥匙检测使能
			confInfo->fctData.otherParmByte.byte = RegData;
		}break;
		case 28:{//单体高压告警
			confInfo->warnData.batVolHigh.value = RegData;
		}break;
		case 29:{//单体低压告警
			confInfo->warnData.batVolLow.value = RegData;
		}break;
		case 30:{//单体压差告警
			confInfo->warnData.batVolDiff.value = RegData;
		}break;
		case 31:{//总压高压告警
			confInfo->warnData.packVolHigh.value = RegData;
		}break;
		case 32:{//总压低压告警
			confInfo->warnData.packVolLow.value = RegData;
		}break;
		case 33:{//功率高温告警
			confInfo->warnData.mosTempHigh = RegData;
		}break;
		case 34:{//环境高温告警
			confInfo->warnData.envTempHigh = RegData;
		}break;
		case 35:{//环境低温告警
			confInfo->warnData.envTemplow = RegData;
		}break;
		case 36:{//充电高温告警
			confInfo->warnData.chgTempHigh = RegData;
		}break;
		case 37:{//充电低温告警
			confInfo->warnData.chgTempLow = RegData;
		}break;
		case 38:{//放电高温告警
			confInfo->warnData.dsgTempHigh = RegData;
		}break;
		case 39:{//放电低温告警
			confInfo->warnData.dsgTempLow = RegData;
		}break;
		case 40:{//容量低告警
			confInfo->warnData.socLow = RegData;
		}break;
		case 41:{//单体一级过压故障
			confInfo->errorData.batVolHigh.value = RegData;
		}break;
		case 42:{//单体一级过压恢复
			confInfo->errorData.batVolHighRecover.value = RegData;
		}break;
		case 43:{//单体一级过压判定时间
			confInfo->errorData.batVolHighTime = RegData;
		}break;
		case 44:{//单体一级欠压故障
			confInfo->errorData.batVolLow.value = RegData;
		}break;
		case 45:{//单体一级欠压恢复
			confInfo->errorData.batVolLowRecover.value = RegData;
		}break;
		case 46:{//单体一级欠压判定时间
			confInfo->errorData.batVolLowTime = RegData;
		}break;
		case 47:{//单体二级过压故障
			confInfo->errorData.sov_vol.value = RegData;
			afe_OV_Config(confInfo->errorData.sov_vol.value,confInfo->errorData.sov_suv_dly_s);
		}break;
		case 48:{//单体二级欠压故障
			confInfo->errorData.suv_vol.value = RegData;
			afe_UV_Config(confInfo->errorData.suv_vol.value,confInfo->errorData.sov_suv_dly_s);
		}break;
		case 49:{//单体二级过压、欠压判定时间
			confInfo->errorData.sov_suv_dly_s = RegData;
			afe_OV_Config(confInfo->errorData.sov_vol.value,confInfo->errorData.sov_suv_dly_s);
			afe_UV_Config(confInfo->errorData.suv_vol.value,confInfo->errorData.sov_suv_dly_s);
		}break;
		case 50:{//单体压差故障
			confInfo->errorData.batVolDiff.value = RegData;
		}break;
		case 51:{//单体压差恢复
			confInfo->errorData.batVolDiffRecover.value = RegData;
		}break;
		case 52:{//单体压差故障判定时间
			confInfo->errorData.batVolDiffTime = RegData;
		}break;
		case 53:{//总压过压故障
			confInfo->errorData.packVolHigh.value = RegData;
		}break;
		case 54:{//总压过压恢复
			confInfo->errorData.packVolHighRecover.value = RegData;
		}break;
		case 55:{//总压过压故障判定时间
			confInfo->errorData.packVolHighTime = RegData;
		}break;
		case 56:{//总压欠压故障
			confInfo->errorData.packVolLow.value = RegData;
		}break;
		case 57:{//总压欠压恢复
			confInfo->errorData.packVolLowRecover.value = RegData;
		}break;
		case 58:{//总压欠压故障判定时间
			confInfo->errorData.packVolLowTime = RegData;
		}break;
		case 59:{//功率过温故障
			confInfo->errorData.mosTempHigh = RegData;
		}break;
		case 60:{//功率过温恢复
			confInfo->errorData.mosTempHighRecover = RegData;
		}break;
		case 61:{//功率过温故障判定时间
			confInfo->errorData.mosTempHighTime = RegData;
		}break;
		case 62:{//环境过温故障
			confInfo->errorData.envTempHigh = RegData;
		}break;
		case 63:{//环境过温恢复
			confInfo->errorData.envTempHighRecover = RegData;
		}break;
		case 64:{//环境过温故障判定时间
			confInfo->errorData.envTempHighTime = RegData;
		}break;
		case 65:{//环境欠温故障
			confInfo->errorData.envTempLow = RegData;
		}break;
		case 66:{//环境欠温恢复
			confInfo->errorData.envTempLowRecover = RegData;
		}break;
		case 67:{//环境欠温故障判定时间
			confInfo->errorData.envTempLowTime = RegData;
		}break;
		case 68:{//充电过温保护
			confInfo->errorData.chgTempHigh = RegData;
		}break;
		case 69:{//充电过温恢复
			confInfo->errorData.chgTempHighRecover = RegData;
		}break;
		case 70:{//充电过温判定时间
			confInfo->errorData.chgTempHighTime = RegData;
		}break;
		case 71:{//充电欠温保护
			confInfo->errorData.chgTempLow = RegData;
		}break;
		case 72:{//充电欠温恢复
			confInfo->errorData.chgTempLowRecover = RegData;
		}break;
		case 73:{//充电欠温判定时间
			confInfo->errorData.chgTempLowTime = RegData;
		}break;
		case 74:{//放电过温保护
			confInfo->errorData.dsgTempHigh = RegData;
		}break;
		case 75:{//放电过温恢复
			confInfo->errorData.dsgTempHighRecover = RegData;
		}break;
		case 76:{//放电过温判定时间
			confInfo->errorData.dsgTempHighTime = RegData;
		}break;
		case 77:{//放电欠温保护
			confInfo->errorData.dsgTempLow = RegData;
		}break;
		case 78:{//放电欠温恢复
			confInfo->errorData.dsgTempLowRecover = RegData;
		}break;
		case 79:{//放电欠温判定时间
			confInfo->errorData.dsgTempLowTime = RegData;
		}break;
		case 80:{//电池温差保护
			confInfo->errorData.batTempDiff = RegData;
		}break;
		case 81:{//电池温差恢复
			confInfo->errorData.batTempDiffRecover = RegData;
		}break;
		case 82:{//电池温差保护判定时间
			confInfo->errorData.batTempDiffTime = RegData;
		}break;
		case 83:{//一级充电过流保护
			confInfo->errorData.chgOverCurrent.value = RegData;
		}break;
		case 84:{//一级充电过流恢复时间
			confInfo->errorData.chgOverCurRecoverTime.value = RegData;
		}break;
		case 85:{//一级充电过流判定时间
			confInfo->errorData.chgOverCurrentTime = RegData;
		}break;
		case 86:{//二级充电过流保护
			confInfo->errorData.chgOverCurrent2.value = RegData;
			afe_OCC1_Config(confInfo->errorData.chgOverCurrent2.value,confInfo->errorData.chgOverCurrent2Time);
		}break;
		case 87:{//二级充电过流恢复时间
			confInfo->errorData.chgOverCur2RecoverTime.value = RegData;
		}break;
		case 88:{//二级充电过流判定时间
			confInfo->errorData.chgOverCurrent2Time = RegData;
			afe_OCC1_Config(confInfo->errorData.chgOverCurrent2.value,confInfo->errorData.chgOverCurrent2Time);
		}break;
		case 89:{//三级充电过流保护
			confInfo->errorData.chgOverCurrent3.value = RegData;
			afe_OCC2_Config(confInfo->errorData.chgOverCurrent3.value,confInfo->errorData.chgOverCurrent3Time,1);
		}break;
		case 90:{//三级充电过流恢复时间
			confInfo->errorData.chgOverCur3RecoverTime.value = RegData;
		}break;
		case 91:{//三级充电过流判定时间
			confInfo->errorData.chgOverCurrent3Time = RegData;
			afe_OCC2_Config(confInfo->errorData.chgOverCurrent3.value,confInfo->errorData.chgOverCurrent3Time,1);
		}break;
		case 92:{//一级放电过流保护
			confInfo->errorData.dsgOverCurrent.value = RegData;
		}break;
		case 93:{//一级放电过流恢复时间
			confInfo->errorData.dsgOverCurRecoverTime.value = RegData;
		}break;
		case 94:{//一级放电过流判定时间
			confInfo->errorData.dsgOverCurrentTime = RegData;
		}break;
		case 95:{//二级放电过流保护
			confInfo->errorData.dsgOverCurrent2.value = RegData;
		}break;
		case 96:{//二级放电过流恢复时间
			confInfo->errorData.dsgOverCur2RecoverTime.value = RegData;
		}break;
		case 97:{//二级放电过流判定时间
			confInfo->errorData.dsgOverCurrent2Time = RegData;
		}break;
		case 98:{//三级放电过流保护
			confInfo->errorData.dsgOverCurrent3.value = RegData;
			afe_OCD1_Config(confInfo->errorData.dsgOverCurrent3.value,confInfo->errorData.dsgOverCurrent3Time);
		}break;
		case 99:{//三级放电过流恢复时间
			confInfo->errorData.dsgOverCur3RecoverTime.value = RegData;
		}break;
		case 100:{//三级放电过流判定时间
			confInfo->errorData.dsgOverCurrent3Time = RegData;
			afe_OCD1_Config(confInfo->errorData.dsgOverCurrent3.value,confInfo->errorData.dsgOverCurrent3Time);
		}break;
		case 101:{//四级放电过流保护
			confInfo->errorData.dsgOverCurrent4.value = RegData;
			afe_OCD2_Config(confInfo->errorData.dsgOverCurrent4.value,confInfo->errorData.dsgOverCurrent4Time.value,1);
		}break;
		case 102:{//四级放电过流恢复时间
			confInfo->errorData.dsgOverCur4RecoverTime.value = RegData;
		}break;
		case 103:{//四级放电过流判定时间
			confInfo->errorData.dsgOverCurrent4Time.value = RegData;
			afe_OCD2_Config(confInfo->errorData.dsgOverCurrent4.value,confInfo->errorData.dsgOverCurrent4Time.value,1);
		}break;
		case 104:{//短路保护
			confInfo->errorData.scdVol.value = RegData;
			afe_SCD_Config(confInfo->errorData.scdVol.value,confInfo->errorData.scdVolTime.value,1);
		}
		break;
		case 105:{//短路判定时间
			confInfo->errorData.scdVolTime.value = RegData;
			afe_SCD_Config(confInfo->errorData.scdVol.value,confInfo->errorData.scdVolTime.value,1);
		}break;
		case 106:{//短路恢复时间
			confInfo->errorData.scdRecoverTime.value = RegData;
		}break;
		case 107:{//充电过流保护锁定次数
			confInfo->errorData.disOverCurLockTimes.value = RegData;
		}break;
		case 108:{//放电过流保护锁定次数
			confInfo->errorData.chgOverCurLockTimes.value = RegData;
		}
		break;
		case 109:{//短路保护锁定次数
			confInfo->errorData.scdLockTimes.value = RegData;
		}break;
		case 110:{//均衡开启电压
			confInfo->balData.openVol.value = RegData;
		}break;
		case 111:{//均衡开启压差
			confInfo->balData.openDiffVol.value = RegData;
		}break;
		case 112:{//均衡关闭压差
			confInfo->balData.endDiffVol.value = RegData;
		}break;
	}

	send_data[0] = 0xAB;
	send_data[1] = WriteSinHoldRegRegData;
	send_data[2] = data[2];
	send_data[3] = data[3];
	send_data[4] = data[4];
	send_data[5] = data[5];

	unsigned short crcValue = XgBmsProtocolCrc(send_data, 6);
	send_data[6] = (crcValue >> 8)& 0xff;
	send_data[7] = crcValue & 0xff; 
	
	modbus_send_data(send_data,8,comNum);	
	saveSysConfData();
}

//发送输入寄存器数据
static void preSetMultiHoldRegData0(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	
	uint8_t index = 0;
	uint8_t RegNum = 0;
	int16_t temp = 0;
	uint16_t i = 0;
	
	SysConfData_t *confInfo = getSysConfData();
	SysRunData_t *runinfo = getSysRunData();
	uint8_t send_data[255];

	uint8_t regAdressH = data[2];
	uint8_t regAdressL = data[3];
	uint16_t startHoldRegAdress = (regAdressH<<8)|regAdressL;
	
	uint8_t RegNumH = data[4];
	uint8_t RegNumL = data[5];
	RegNum =(RegNumH<<8)|RegNumL;
	index = 6;
	while(i<RegNum){
		switch(startHoldRegAdress+i){
			case 1:{//电池类型
				index += 1;
				confInfo->fctData.batType = data[index++] & 0xff;
			}break;
			case 2:{//电池串数
				index += 1;
				confInfo->fctData.batNum = data[index++] & 0xff;
				Judge_BatNum();
			}break;
			case 3:{//硬件ID
				memset(confInfo->fctData.hdSerial, 0, 12);
				memcpy(confInfo->fctData.hdSerial, &data[index], 12);
				index += 12;
			}break;
			case 9:{//电池BT码
				memset(confInfo->fctData.BtNum, 0, 24);
				memcpy(confInfo->fctData.BtNum, &data[index], 24);
				index += 24;
			}break;
			case 21:{//标称容量
				confInfo->fctData.normalCap.byte[1] = data[index++] & 0xff;
				confInfo->fctData.normalCap.byte[0] = data[index++] & 0xff;
				runinfo->norCap_mAmS = ((uint64_t)confInfo->fctData.normalCap.value) * 360 * 1000 * 1000; // 实际容量初始化
			}break;
			case 22:{//实际容量
				confInfo->fctData.realCap.byte[1] = data[index++] & 0xff;
				confInfo->fctData.realCap.byte[0] = data[index++] & 0xff;
				runinfo->realCap_mAms = ((uint64_t)confInfo->fctData.realCap.value) * 360 * 1000 * 1000;  // 实际容量初始化
				runinfo->batSoh = runinfo->realCap_mAms * 100 / runinfo->norCap_mAmS;
			}break;
			case 23:{//循环次数
				confInfo->fctData.cycleTimes.byte[1] = data[index++] & 0xff;
				confInfo->fctData.cycleTimes.byte[0] = data[index++] & 0xff;
			}break;
			case 24:{//预充时间
				confInfo->fctData.preChargeTime.byte[1] = data[index++] & 0xff;
				confInfo->fctData.preChargeTime.byte[0] = data[index++] & 0xff;
			}break;
			case 25:{//单体关机电压
				confInfo->fctData.poweroff_vol.byte[1] = data[index++] & 0xff;
				confInfo->fctData.poweroff_vol.byte[0] = data[index++] & 0xff;
			}break;
			case 26:{//唤醒电流
				confInfo->fctData.wakeupCurrent.byte[1] = data[index++] & 0xff;
				confInfo->fctData.wakeupCurrent.byte[0] = data[index++] & 0xff;
			}break;
			case 27:{//钥匙检测使能
				index += 1;
				confInfo->fctData.otherParmByte.byte = data[index++] & 0xff;
			}break;
			case 28:{//单体高压告警
				confInfo->warnData.batVolHigh.byte[1] = data[index++] & 0xff;
				confInfo->warnData.batVolHigh.byte[0] = data[index++] & 0xff;
			}break;
			case 29:{//单体低压告警
				confInfo->warnData.batVolLow.byte[1] = data[index++] & 0xff;
				confInfo->warnData.batVolLow.byte[0] = data[index++] & 0xff;
			}break;
			case 30:{//单体压差告警
				confInfo->warnData.batVolDiff.byte[1] = data[index++] & 0xff;
				confInfo->warnData.batVolDiff.byte[0] = data[index++] & 0xff;
			}break;
			case 31:{//总压高压告警
				confInfo->warnData.packVolHigh.byte[1] = data[index++] & 0xff;
				confInfo->warnData.packVolHigh.byte[0] = data[index++] & 0xff;
			}break;
			case 32:{//总压低压告警
				confInfo->warnData.packVolLow.byte[1] = data[index++] & 0xff;
				confInfo->warnData.packVolLow.byte[0] = data[index++] & 0xff;
			}break;
			case 33:{//功率高温告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.mosTempHigh = temp;
			}break;
			case 34:{//环境高温告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.envTempHigh = temp;
			}break;
			case 35:{//环境低温告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.envTemplow = temp;
			}break;
			case 36:{//充电高温告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.chgTempHigh = temp;
			}break;
			case 37:{//充电低温告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.chgTempLow = temp;
			}break;
			case 38:{//放电高温告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.dsgTempHigh = temp;
			}break;
			case 39:{//放电低温告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.dsgTempLow = temp;
			}break;
			case 40:{//容量低告警
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->warnData.socLow = temp;
			}break;
			case 41:{//单体一级过压故障
				confInfo->errorData.batVolHigh.byte[1] = data[index++] & 0xff;
				confInfo->errorData.batVolHigh.byte[0] = data[index++] & 0xff;
			}break;
			case 42:{//单体一级过压恢复
				confInfo->errorData.batVolHighRecover.byte[1] = data[index++] & 0xff;
				confInfo->errorData.batVolHighRecover.byte[0] = data[index++] & 0xff;
			}break;
			case 43:{//单体一级过压判定时间
				index += 1;
				confInfo->errorData.batVolHighTime = data[index++] & 0xff;
			}break;
			case 44:{//单体一级欠压故障
				confInfo->errorData.batVolLow.byte[1] = data[index++] & 0xff;
				confInfo->errorData.batVolLow.byte[0] = data[index++] & 0xff;
			}break;
			case 45:{//单体一级欠压恢复
				confInfo->errorData.batVolLowRecover.byte[1] = data[index++] & 0xff;
				confInfo->errorData.batVolLowRecover.byte[0] = data[index++] & 0xff;
			}break;
			case 46:{//单体一级欠压判定时间
				index += 1;
				confInfo->errorData.batVolLowTime = data[index++] & 0xff;
			}break;
			case 47:{//单体二级过压故障
				confInfo->errorData.sov_vol.byte[1] = data[index++] & 0xff;
				confInfo->errorData.sov_vol.byte[0] = data[index++] & 0xff;				   // 设定单体欠压和过压
				afe_OV_Config(confInfo->errorData.sov_vol.value,confInfo->errorData.sov_suv_dly_s);
			}break;
			case 48:{//单体二级欠压故障
				confInfo->errorData.suv_vol.byte[1] = data[index++] & 0xff;
				confInfo->errorData.suv_vol.byte[0] = data[index++] & 0xff;				   // 设定单体欠压和过压
				afe_UV_Config(confInfo->errorData.suv_vol.value,confInfo->errorData.sov_suv_dly_s);
			}break;
			case 49:{//单体二级过压、欠压判定时间
				index += 1;
				confInfo->errorData.sov_suv_dly_s = data[index++] & 0xff;
				afe_OV_Config(confInfo->errorData.sov_vol.value,confInfo->errorData.sov_suv_dly_s);
				afe_UV_Config(confInfo->errorData.suv_vol.value,confInfo->errorData.sov_suv_dly_s);
			}break;
			case 50:{//单体压差故障
				confInfo->errorData.batVolDiff.byte[1] = data[index++] & 0xff;
				confInfo->errorData.batVolDiff.byte[0] = data[index++] & 0xff;
			}break;
			case 51:{//单体压差恢复
				confInfo->errorData.batVolDiffRecover.byte[1] = data[index++] & 0xff;
				confInfo->errorData.batVolDiffRecover.byte[0] = data[index++] & 0xff;
			}break;
			case 52:{//单体压差故障判定时间
				index += 1;
				confInfo->errorData.batVolDiffTime = data[index++] & 0xff;
			}break;
			case 53:{//总压过压故障
				confInfo->errorData.packVolHigh.byte[1] = data[index++] & 0xff;
				confInfo->errorData.packVolHigh.byte[0] = data[index++] & 0xff;
			}break;
			case 54:{//总压过压恢复
				confInfo->errorData.packVolHighRecover.byte[1] = data[index++] & 0xff;
				confInfo->errorData.packVolHighRecover.byte[0] = data[index++] & 0xff;
			}break;
			case 55:{//总压过压故障判定时间
				index += 1;
				confInfo->errorData.packVolHighTime = data[index++] & 0xff;
			}break;
			case 56:{//总压欠压故障
				confInfo->errorData.packVolLow.byte[1] = data[index++] & 0xff;
				confInfo->errorData.packVolLow.byte[0] = data[index++] & 0xff;
			}break;
			case 57:{//总压欠压恢复
				confInfo->errorData.packVolLowRecover.byte[1] = data[index++] & 0xff;
				confInfo->errorData.packVolLowRecover.byte[0] = data[index++] & 0xff;
			}break;
			case 58:{//总压欠压故障判定时间
				index += 1;
				confInfo->errorData.packVolLowTime = data[index++] & 0xff;
			}break;
			case 59:{//功率过温故障
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.mosTempHigh = temp;
			}break;
			case 60:{//功率过温恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.mosTempHighRecover = temp;
			}break;
			case 61:{//功率过温故障判定时间
				index += 1;
				confInfo->errorData.mosTempHighTime = data[index++] & 0xff;
			}break;
			case 62:{//环境过温故障
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.envTempHigh = temp;
			}break;
			case 63:{//环境过温恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.envTempHighRecover = temp;
			}break;
			case 64:{//环境过温故障判定时间
				index += 1;
				confInfo->errorData.envTempHighTime = data[index++] & 0xff;
			}break;
			case 65:{//环境欠温故障
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.envTempLow = temp;
			}break;
			case 66:{//环境欠温恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.envTempLowRecover = temp;
			}break;
			case 67:{//环境欠温故障判定时间
				index += 1;
				confInfo->errorData.envTempLowTime = data[index++] & 0xff;
			}break;
			case 68:{//充电过温保护
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.chgTempHigh = temp;
			}break;
			case 69:{//充电过温恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.chgTempHighRecover = temp;
			}break;
			case 70:{//充电过温判定时间
				index += 1;
				confInfo->errorData.chgTempHighTime = data[index++] & 0xff;
			}break;
			case 71:{//充电欠温保护
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.chgTempLow = temp;
			}break;
			case 72:{//充电欠温恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.chgTempLowRecover = temp;
			}break;
			case 73:{//充电欠温判定时间
				index += 1;
				confInfo->errorData.chgTempLowTime = data[index++] & 0xff;
			}break;
			case 74:{//放电过温保护
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.dsgTempHigh = temp;
			}break;
			case 75:{//放电过温恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.dsgTempHighRecover = temp;
			}break;
			case 76:{//放电过温判定时间
				index += 1;
				confInfo->errorData.dsgTempHighTime = data[index++] & 0xff;
			}break;
			case 77:{//放电欠温保护
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.dsgTempLow = temp;
			}break;
			case 78:{//放电欠温恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.dsgTempLowRecover = temp;
			}break;
			case 79:{//放电欠温判定时间
				index += 1;
				confInfo->errorData.dsgTempLowTime = data[index++] & 0xff;
			}break;
			case 80:{//电池温差保护
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.batTempDiff = temp;
			}break;
			case 81:{//电池温差恢复
				temp = data[index++] & 0xff;
				temp <<= 8;
				temp |= data[index++] & 0xff;
				confInfo->errorData.batTempDiffRecover = temp;
			}break;
			case 82:{//电池温差保护判定时间
				index += 1;
				confInfo->errorData.batTempDiffTime = data[index++] & 0xff;
			}break;
			case 83:{//一级充电过流保护
				confInfo->errorData.chgOverCurrent.byte[1] = data[index++] & 0xff;
				confInfo->errorData.chgOverCurrent.byte[0] = data[index++] & 0xff;
			}break;
			case 84:{//一级充电过流恢复时间
				confInfo->errorData.chgOverCurRecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.chgOverCurRecoverTime.byte[0] = data[index++] & 0xff;
			}break;
			case 85:{//一级充电过流判定时间
				index += 1;
				confInfo->errorData.chgOverCurrentTime = data[index++] & 0xff;
			}break;
			case 86:{//二级充电过流保护
				confInfo->errorData.chgOverCurrent2.byte[1] = data[index++] & 0xff;
				confInfo->errorData.chgOverCurrent2.byte[0] = data[index++] & 0xff;
				afe_OCC1_Config(confInfo->errorData.chgOverCurrent2.value,confInfo->errorData.chgOverCurrent2Time);
			}break;
			case 87:{//二级充电过流恢复时间
				confInfo->errorData.chgOverCur2RecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.chgOverCur2RecoverTime.byte[0] = data[index++] & 0xff;
			}break;
			case 88:{//二级充电过流判定时间
				index += 1;
				confInfo->errorData.chgOverCurrent2Time = data[index++] & 0xff;
				afe_OCC1_Config(confInfo->errorData.chgOverCurrent2.value,confInfo->errorData.chgOverCurrent2Time);
			}break;
			case 89:{//三级充电过流保护
				confInfo->errorData.chgOverCurrent3.byte[1] = data[index++] & 0xff;
				confInfo->errorData.chgOverCurrent3.byte[0] = data[index++] & 0xff;
				afe_OCC2_Config(confInfo->errorData.chgOverCurrent3.value,confInfo->errorData.chgOverCurrent3Time,1);
			}break;
			case 90:{//三级充电过流恢复时间
				confInfo->errorData.chgOverCur3RecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.chgOverCur3RecoverTime.byte[0] = data[index++] & 0xff;
			}break;
			case 91:{//三级充电过流判定时间
				index += 1;
				confInfo->errorData.chgOverCurrent3Time = data[index++] & 0xff;
				afe_OCC2_Config(confInfo->errorData.chgOverCurrent3.value,confInfo->errorData.chgOverCurrent3Time,1);
			}break;
			case 92:{//一级放电过流保护
				confInfo->errorData.dsgOverCurrent.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCurrent.byte[0] = data[index++] & 0xff;
			}break;
			case 93:{//一级放电过流恢复时间
				confInfo->errorData.dsgOverCurRecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCurRecoverTime.byte[0] = data[index++] & 0xff;
			}break;
			case 94:{//一级放电过流判定时间
				index += 1;
				confInfo->errorData.dsgOverCurrentTime = data[index++] & 0xff;
			}break;
			case 95:{//二级放电过流保护
				confInfo->errorData.dsgOverCurrent2.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCurrent2.byte[0] = data[index++] & 0xff;
			}break;
			case 96:{//二级放电过流恢复时间
				confInfo->errorData.dsgOverCur2RecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCur2RecoverTime.byte[0] = data[index++] & 0xff;
			}break;
			case 97:{//二级放电过流判定时间
				index += 1;
				confInfo->errorData.dsgOverCurrent2Time = data[index++] & 0xff;
			}break;
			case 98:{//三级放电过流保护
				confInfo->errorData.dsgOverCurrent3.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCurrent3.byte[0] = data[index++] & 0xff;
				afe_OCD1_Config(confInfo->errorData.dsgOverCurrent3.value,confInfo->errorData.dsgOverCurrent3Time);
			}break;
			case 99:{//三级放电过流恢复时间
				confInfo->errorData.dsgOverCur3RecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCur3RecoverTime.byte[0] = data[index++] & 0xff;
			}break;
			case 100:{//三级放电过流判定时间
				index += 1;
				confInfo->errorData.dsgOverCurrent3Time = data[index++] & 0xff;
				afe_OCD1_Config(confInfo->errorData.dsgOverCurrent3.value,confInfo->errorData.dsgOverCurrent3Time);
			}break;
			case 101:{//四级放电过流保护
				confInfo->errorData.dsgOverCurrent4.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCurrent4.byte[0] = data[index++] & 0xff;
				afe_OCD2_Config(confInfo->errorData.dsgOverCurrent4.value,confInfo->errorData.dsgOverCurrent4Time.value,1);
			}break;
			case 102:{//四级放电过流恢复时间
				confInfo->errorData.dsgOverCur4RecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCur4RecoverTime.byte[0] = data[index++] & 0xff;
			}break;
			case 103:{//四级放电过流判定时间
				confInfo->errorData.dsgOverCurrent4Time.byte[1] = data[index++] & 0xff;
				confInfo->errorData.dsgOverCurrent4Time.byte[0] = data[index++] & 0xff;
				afe_OCD2_Config(confInfo->errorData.dsgOverCurrent4.value,confInfo->errorData.dsgOverCurrent4Time.value,1);
			}break;
			case 104:{//短路保护
				confInfo->errorData.scdVol.byte[1] = data[index++] & 0xff;
				confInfo->errorData.scdVol.byte[0] = data[index++] & 0xff;
				afe_SCD_Config(confInfo->errorData.scdVol.value,confInfo->errorData.scdVolTime.value,1);
			}break;
			case 105:{//短路判定时间
				confInfo->errorData.scdVolTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.scdVolTime.byte[0] = data[index++] & 0xff;
				afe_SCD_Config(confInfo->errorData.scdVol.value,confInfo->errorData.scdVolTime.value,1);
			}break;
			case 106:{//短路恢复时间
				confInfo->errorData.scdRecoverTime.byte[1] = data[index++] & 0xff;
				confInfo->errorData.scdRecoverTime.byte[0] = data[index++] & 0xff;				   // 设定短路及判定时间
			}break;
			case 107:{//充电过流保护锁定次数
				confInfo->errorData.chgOverCurLockTimes.byte[1] = data[index++] & 0xff;
				confInfo->errorData.chgOverCurLockTimes.byte[0] = data[index++] & 0xff;
			}break;
			case 108:{//放电过流保护锁定次数
				confInfo->errorData.disOverCurLockTimes.byte[1] = data[index++] & 0xff;
				confInfo->errorData.disOverCurLockTimes.byte[0] = data[index++] & 0xff;
			}break;
			case 109:{//短路保护锁定次数
				confInfo->errorData.scdLockTimes.byte[1] = data[index++] & 0xff;
				confInfo->errorData.scdLockTimes.byte[0] = data[index++] & 0xff;
			}break;
			case 110:{//均衡开启电压
				confInfo->balData.openVol.byte[1] = data[index++] & 0xff;
				confInfo->balData.openVol.byte[0] = data[index++] & 0xff;
			}break;
			case 111:{//均衡开启压差
				confInfo->balData.openDiffVol.byte[1] = data[index++] & 0xff;
				confInfo->balData.openDiffVol.byte[0] = data[index++] & 0xff;
			}break;
			case 112:{//均衡关闭压差
				confInfo->balData.endDiffVol.byte[1] = data[index++] & 0xff;
				confInfo->balData.endDiffVol.byte[0] = data[index++] & 0xff;
			}break;
			case 113:{//电流校准
				//uint32_t stdCurrent = (data[6]<<24)|(data[7]<<16)|(data[8]<<8)|data[9];
				uint32_t stdCurrent = data[6]&0xff;
				stdCurrent <<= 8;
				stdCurrent |= data[7]&0xff;
				stdCurrent <<= 8;
				stdCurrent |= data[8]&0xff;
				stdCurrent <<= 8;
				stdCurrent |= data[9]&0xff;
				//printf("stdCurrent = %dmA\n",stdCurrent);
				float caliValue = ((float)(stdCurrent)) / ((float)abs(runinfo->batRawCur));
				if (caliValue >= 0.5 && caliValue <= 1.5){
					confInfo->caliData.curRadio = (unsigned short)(caliValue * 10000.0);
				}else{
					
				}
			}break;
			case 115:{//电压校准
				unsigned short chkVol = 0;
				unsigned short stdVol = 0;
				unsigned char batNum = 0;
				batNum = (data[6]<<8)|data[7];
				stdVol = (data[8]<<8)|data[9];
				chkVol = runinfo->batVol[(batNum - 1) % 32];
				unsigned int adcCaliValue = stdVol;
				adcCaliValue = adcCaliValue * 10000 / chkVol;
				if (adcCaliValue > 15000 || adcCaliValue < 5000){

				}else{

				}
				if (batNum == 1){
					confInfo->caliData.lowAdcRadio = confInfo->caliData.lowAdcRadio * adcCaliValue / 10000;
				}
				if (batNum == 17){
					confInfo->caliData.highAdcRadio = confInfo->caliData.highAdcRadio * adcCaliValue / 10000;
				}
			}
			break;
			case 116:{//时间校准
				char stdTimeStr[20] = {0};
				memset(stdTimeStr, 0, 20);
				stdTimeStr[0] = data[index++];
				stdTimeStr[1] = data[index++];
				stdTimeStr[2] = data[index++];
				stdTimeStr[3] = data[index++];
				stdTimeStr[4] = data[index++];
				stdTimeStr[5] = data[index++];
				set_hex_date_time(stdTimeStr);
//				runinfo->sysStartTime_min = getTimeStamp()/60;
			}break;
		}
		i++;
	}
	
	send_data[0] = 0xAB;
	send_data[1] = WriteMulHoldRegRegData;
	send_data[2] = data[2];
	send_data[3] = data[3];
	send_data[4] = data[4];
	send_data[5] = data[5];
	unsigned short crcValue = XgBmsProtocolCrc(send_data, 6);
	send_data[6] = (crcValue >> 8)& 0xff;
	send_data[7] = crcValue & 0xff; 
	modbus_send_data(send_data,8,comNum);
	saveSysConfData();
}

static void SendSoft_Reset(uint8_t comNum){
	uint8_t send_data[255];
	uint16_t index = 0;
	
	SysConfData_t *confInfo = getSysConfData();
	sysErrRcdClear();
	
	send_data[index++] = 0xAB;
	send_data[index++] = ForcedSingleCoil;
	send_data[index++] = 0x00;
	send_data[index++] = 0x07;
	send_data[index++] = 0xFF;
	send_data[index++] = 0x00;
	
	unsigned short crcValue = XgBmsProtocolCrc(send_data,index);
	send_data[index++] = (crcValue >> 8)& 0xff;
	send_data[index++] = crcValue & 0xff; 
	
//	for(uint8_t i=0;i<index;i++){
//		printf("[%d]=%x\n",i,send_data[i]);
//	}
//	printf("\n");
	modbus_send_data(send_data,index,comNum);
}

static void SendForcedSingleCoil(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	uint8_t index = 0;
	bool rebootFlag = false;
	uint16_t SwFlag = 0;
	uint16_t CoilFlag = 0;
	SysConfData_t *confInfo = getSysConfData();
	SysRunData_t *runinfo = getSysRunData();
	uint8_t send_data[255];
	
	uint16_t coilAdressH = data[2];
	uint16_t coilAdressL = data[3];
	uint16_t coilAdress = (coilAdressH<<8)|coilAdressL;
	
	
	uint8_t CoilFlagH = data[4];
	uint8_t CoilFlagL = data[5];
	CoilFlag =(CoilFlagH<<8)|CoilFlagL;
	if(CoilFlag == 0xff00){
		SwFlag = 1;
	}
	if(CoilFlag == 0x0000){
		SwFlag = 0;
	}

	switch (coilAdress){
		case 1:{ // 充电开关
			chgOptionEnable(SwFlag);
		}break;
		case 2: {// 放电开关
			dsgOptionEnable(SwFlag);
		}break;
		case 3: {// 预充开关
			afe_prechg_mos_ctrl(SwFlag);
		}break;
		case 4: {// 均衡开关
			afe_balance_enable(SwFlag);
		}break;
		case 5: {// 加热开关
			afe_heat_mos_ctrl(SwFlag);
		}break;
		case 6:	{// OTA开关
			runinfo->sysSwState.bits.SW_OTA = 1;
		}break;
		case 7:	{// 重启
//			SendSoft_Reset(comNum);
			rebootFlag = true;
		}break;
		case 8:	{// 关机
			sleep_enter_control();
		}break;
		case 9:	{// 唤醒
			
		}break;
	}
	
	send_data[0] = 0xAB;
	send_data[1] = ForcedSingleCoil;
	send_data[2] = data[2];
	send_data[3] = data[3];
	send_data[4] = data[4];
	send_data[5] = data[5];

	unsigned short crcValue = XgBmsProtocolCrc(send_data, 6);
	send_data[6] = (crcValue >> 8)& 0xff;
	send_data[7] = crcValue & 0xff; 
	
//	for(uint8_t i=0;i<index;i++){
//			printf("[%d]=%x\n",i,send_data[i]);
//	}
//	printf("\n");
	modbus_send_data(send_data,8,comNum);
	if(rebootFlag==true){
		rebootFlag = false;
		afe_chg_mos_ctrl(false);
		afe_dsg_mos_ctrl(false);
		Soft_Reset();
	}
	if(runinfo->sysSwState.bits.SW_OTA == 1){
		usart4_init(115200);
	}
}

static void SendReadFaultData(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	uint16_t index = 0;
	XgErrRecord *errInfo = getSysErrRcdInfo();
	uint8_t send_data[512];
	send_data[index++] = data[0];
	send_data[index++] = ExtendedFunction;
	send_data[index++] = ReadFaultProfile;
	send_data[index++] = errInfo->recordNum;
	if (errInfo->recordNum > 30){
		printf("error record num error,max 30,record num:%d\n", errInfo->recordNum);
		return;
	}
	unsigned short i = 0;
	for (i = 0; i < errInfo->recordNum; i++){
		send_data[index++] = 0;
		send_data[index++] = errInfo->recordData[i].errorCode;
		send_data[index++] = (errInfo->recordData[i].occurTimes >> 8) & 0xff;
		send_data[index++] = errInfo->recordData[i].occurTimes & 0xff;
		memcpy(&send_data[index], errInfo->recordData[i].latestOccurTime, 6);
		index += 6;
	}
	unsigned short crcValue = XgBmsProtocolCrc(send_data, 6);
	send_data[index++] = (crcValue >> 8)& 0xff;
	send_data[index++] = crcValue & 0xff; 
//	for(uint16_t i=0;i<index;i++){
//			printf("[%d]=%x\n",i,send_data[i]);
//	}
//	printf("\n");
	modbus_send_data(send_data,index,comNum);
}

static void SendClearFaultData(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	uint8_t send_data[255];
	uint16_t index = 0;
	SysConfData_t *confInfo = getSysConfData();
	sysErrRcdClear();
	send_data[index++] = 0xAB;
	send_data[index++] = ExtendedFunction;
	send_data[index++] = ClearFaultProfile;
	send_data[index++] = 0xAA;
	unsigned short crcValue = XgBmsProtocolCrc(send_data,index);
	send_data[index++] = (crcValue >> 8)& 0xff;
	send_data[index++] = crcValue & 0xff; 
	modbus_send_data(send_data,index,comNum);
}

static void getErrlogNumMore(uint8_t comNum){
	SysConfData_t *confInfo = getSysConfData();
	uint16_t index = 0;
	XgErrRecord *errInfo = getSysErrRcdInfo();
	uint8_t send_data[256];
	send_data[index++] = 0xAB;
	send_data[index++] = ExtendedFunction;
	send_data[index++] = ReadFaultLog;
	send_data[index++] = 0xaa;
	printf("LENTH=%d\n",XG_STORE_HIST_DATA_LENGTH);
	for (unsigned char i = 0; i < XG_STORE_HIST_DATA_LENGTH-7; i++){
		send_data[index++] = getTsdbErrLog()->ErrLogData[i];
	}
	unsigned short crcValue = XgBmsProtocolCrc(send_data, index);
	send_data[index++] = (crcValue >> 8)& 0xff;
	send_data[index++] = crcValue & 0xff; 
//	for(uint16_t i=0;i<index;i++){
//			printf("[%d]=%x\n",i,send_data[i]);
//	}
//	printf("\n");
	modbus_send_data(send_data,index,comNum);
}
	
static void getErrlogNumLast(uint8_t comNum){
	SysConfData_t *confInfo = getSysConfData();
	uint16_t index = 0;
	XgErrRecord *errInfo = getSysErrRcdInfo();
	uint8_t send_data[256];
	send_data[index++] = 0xAB;
	send_data[index++] = ExtendedFunction;
	send_data[index++] = ReadFaultLog;
	send_data[index++] = 0xbb;
	for (unsigned char i = 0; i < XG_STORE_HIST_DATA_LENGTH - 7; i++){
		send_data[index++] = getTsdbErrLog()->ErrLogData[i];
	}
	unsigned short crcValue = XgBmsProtocolCrc(send_data, index);
	send_data[index++] = (crcValue >> 8)& 0xff;
	send_data[index++] = crcValue & 0xff; 
	modbus_send_data(send_data,index,comNum);
}

static void SendReadFaultLogData(unsigned char *data,unsigned short dataLen,uint8_t comNum){

	unsigned char dataRecordLogRead = data[3];
	switch (dataRecordLogRead){
		case readFirstLog:{ // 读取第一条
			getTsdbErrLog()->totalNum = getErrlogNum();
			getTsdbErrLog()->needReadRecordNum = 1;
		}break;
		case readNextLog:{ // 读取下一条
			getTsdbErrLog()->needReadRecordNum++;
		}break;
	}
	if (getTsdbErrLog()->needReadRecordNum <= getTsdbErrLog()->totalNum){
		read_record(getTsdbErrLog()->needReadRecordNum);
			getErrlogNumMore(comNum);
			memset(getTsdbErrLog()->ErrLogData, 0, sizeof(XG_STORE_HIST_DATA_LENGTH));
	}else{
		getErrlogNumLast(comNum);
	}
}

static void SendClearFaultLogData(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	uint8_t send_data[255];
	SysConfData_t *confInfo = getSysConfData();
	clear_record();
	send_data[0] = 0xAB;
	send_data[1] = ExtendedFunction;
	send_data[2] = ClearFaultLog;
	send_data[3] = 0xAA;
	unsigned short crcValue = XgBmsProtocolCrc(send_data, 4);
	send_data[4] = (crcValue >> 8)& 0xff;
	send_data[5] = crcValue & 0xff; 
	modbus_send_data(send_data,6,comNum);
}

static void SendUpgradeInstruction(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	uint8_t send_data[255];
	SysConfData_t *confInfo = getSysConfData();
	getSysRunData()->sysSwState.bits.SW_OTA = 1;
	send_data[0] = 0xAB;
	send_data[1] = 0X05;
	send_data[2] = 0x00;
	send_data[3] = 0x06;
	send_data[4] = 0xFF;
	send_data[5] = 0x00;
	unsigned short crcValue = XgBmsProtocolCrc(send_data, 6);
	send_data[6] = (crcValue >> 8)& 0xff;
	send_data[7] = crcValue & 0xff; 
	modbus_send_data(send_data,8,comNum);
}


static void ModBusData(unsigned char *data,unsigned short dataLen,uint8_t comNum){
	uint8_t funcCode = data[1];
	uint8_t SubCommand = data[2];
	switch(funcCode){
		case ReadInputRegRegData:{//读输入寄存器0x04
			uint16_t regStartAddr = data[2];
			regStartAddr <<= 8;
			regStartAddr |= data[3];
			uint16_t regCount = data[4];
			regCount <<= 8;
			regCount |= data[5];
			readInputRegData(regStartAddr,regCount,comNum);
		}break;
		case ReadHoldRegRegData:{//读保持寄存器0x03
			uint16_t regStartAddr = data[2];
			regStartAddr <<= 8;
			regStartAddr |= data[3];
			uint16_t regCount = data[4];
			regCount <<= 8;
			regCount |= data[5];
			readMultiHoldRegData(regStartAddr,regCount,comNum);
		}break;
		case WriteSinHoldRegRegData:{//写单个保持寄存器0x06
			preSetSinHoldRegData(data,dataLen,comNum);	
		}break;
		case WriteMulHoldRegRegData:{//写多个保持寄存器0x10
			preSetMultiHoldRegData0(data,dataLen,comNum);	
		}break;
		case ForcedSingleCoil:{////强制单线圈0x05
			 SendForcedSingleCoil(data,dataLen,comNum);
		}break;		
		case ExtendedFunction:{//扩展功能0x80
			switch (SubCommand){
				case ReadFaultProfile:{//读取故障记录0x01
					 SendReadFaultData(data,dataLen,comNum);
				}break;
				case ClearFaultProfile:{//清除故障记录0x02
					 SendClearFaultData(data,dataLen,comNum);
				}break;
				case ReadFaultLog:{//读取故障日志0x03
					 SendReadFaultLogData(data,dataLen,comNum);
				}break;
				case ClearFaultLog:{//清除故障日志0x04
					 SendClearFaultLogData(data,dataLen,comNum);
				}break;
			}
		}break;		
		case StartUpgrade:{//启动升级0x81
			SendUpgradeInstruction(data,dataLen,comNum);
		}break;
	}
}

//上位机ModBus协议解析,带数据粘包之后的解包功能
void modbus_data_parse(uint8_t *data,uint16_t len,uint8_t comNum){
	SysConfData_t *confInfo = getSysConfData();
	SysRunData_t  *runInfo = getSysRunData();
	for(uint16_t i = 0;i<len;){
		if(data[0 + i] != 0xAB && data[0 + i] != 0xFF){//地址为0xAB
			//printf(" ModBus Address error\n");
			i++;
			continue;
		}
		uint8_t funcCode = data[1 + i]&0xff;
		if(funcCode>130 || funcCode<1){//功能码为1-130
			//printf(" ModBus data invalid func code\n");
			i++;
			continue;
		}
		uint8_t cmdLen = 0;
		switch(funcCode){//根据功能码求解数据长度
			case ReadInputRegRegData:{//读输入寄存器0x04
				cmdLen = 8;
			}break;
			case ReadHoldRegRegData:{//读保持寄存器0x03
				cmdLen = 8;
			}break;
			case WriteSinHoldRegRegData:{//写单个保持寄存器0x06
				cmdLen = 8;
			}break;
			case WriteMulHoldRegRegData:{//写多个保持寄存器0x10
				uint16_t regStartAddr = ((((uint16_t)data[2])<<8) | data[3]);
				uint16_t regCount = ((((uint16_t)data[4])<<8) | data[5]);
				cmdLen = regCount * 2 + 8;
			}break;
			case ForcedSingleCoil:{////强制单线圈0x05
				cmdLen = 8;
			}break;		
			case ExtendedFunction:{//扩展功能0x80
				cmdLen = 6;
			}break;		
			default:{//
				i++;
				continue;
			}break;
		}
		int mtCrcValue = XgBmsProtocolCrc(&data[i],cmdLen - 2);
		char crcL = mtCrcValue & 0xff;
		char crcH = (mtCrcValue >> 8) & 0xff;
		if (crcH != data[i + cmdLen - 2] || crcL != data[i + cmdLen - 1]) {//crc校验不通过
			//printf("ModBus data crc check not pass\n");
			i++ ;
			continue;
		}else{
			ModBusData(&data[i + 0],cmdLen,comNum);
			i += cmdLen;
		}
	}
}

//上位机ModBus协议解析
void modbus_data(uint8_t *data,uint16_t len,uint8_t comNum){
	SysConfData_t *confInfo = getSysConfData();
	SysRunData_t  *runInfo = getSysRunData();
	if(data[0] != 0xAB && data[0] != 0xFF){//地址为0xAB
		return;
	}
	if(data[1]>130 || data[1]<1){//功能码为1-130
		printf(" ModBus data invalid func code\n");
		return;
	}
	uint16_t ModBusAdr = data[0];

	int mtCrcValue = XgBmsProtocolCrc(data,len - 2);
	char crcL = mtCrcValue & 0xff;
	char crcH = (mtCrcValue >> 8) & 0xff;
	if (crcH != data[len - 2] || crcL != data[len - 1]) {//crc校验不通过
		printf("ModBus data crc check not pass\n");
		return ;
	}
	ModBusData(&data[0],len,comNum);	
}
